home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / dgsay.exe / DGINIT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-06-29  |  27.5 KB  |  972 lines

  1. {
  2.  ╔═════════════════════════════════════════════════════════════════════════╗
  3.  ║                                                                         ║
  4.  ║        TITLE :      DGINIT.TPU,  Version 8906.01                        ║
  5.  ║      PURPOSE :      Various wheels.  Don't reinvent.                    ║
  6.  ║       AUTHOR :      David Gerrold, CompuServe ID:  70307,544            ║
  7.  ║  _____________________________________________________________________  ║
  8.  ║                                                                         ║
  9.  ║  This is not public domain software.  This is shareware.                ║
  10.  ║  This software is copyright 1989, by David Gerrold.                     ║
  11.  ║                                                                         ║
  12.  ║        The Brass Cannon Corporation                                     ║
  13.  ║        9420 Reseda Blvd., #804                                          ║
  14.  ║        Northridge, CA 91324-2932.                                       ║
  15.  ║                                                                         ║
  16.  ║  If you find this code useful, a donation of $25 is requested --        ║
  17.  ║  not to me, but to the AIDS Project Los Angeles.  Donations may         ║
  18.  ║  be forwarded via the Brass Cannon address.  Thank you.                 ║
  19.  ║                                                                         ║
  20.  ╚═════════════════════════════════════════════════════════════════════════╝
  21.                                                                             }
  22. { ========================================================================= }
  23. {  Compiler Directives :                                                    }
  24. { ========================================================================= }
  25.  
  26. {$R-}    {Range checking off}
  27. {$B+}    {Boolean complete evaluation on}
  28. {$S+}    {Stack checking on}
  29. {$I+}    {I/O checking on}
  30. {$N+,E+} {Simulate numeric coprocessor}
  31. {$M 65500,16384,655360} {Turbo 3 default stack and heap}
  32. {$V-}    {Variable range checking off}
  33.  
  34. { ========================================================================= }
  35. { ========================================================================= }
  36.  
  37. UNIT DGinit;
  38. { includes time and date functions }
  39.  
  40. { ========================================================================= }
  41. INTERFACE
  42. { ========================================================================= }
  43.  
  44. USES
  45.   Dos,                                           { TP5.5 unit }
  46.   TpDos,                                         { Turbo Professional unit }
  47.   TpCrt,                                         { Turbo Professional unit }
  48.   TpString,                                      { Turbo Professional unit }
  49.   TpWindow;                                      { Turbo Professional unit }
  50.  
  51. { ========================================================================= }
  52.  
  53. TYPE
  54.   String2    = string [2];
  55.   String3    = string [3];
  56.   String6    = string [6];
  57.   String12   = string [12];
  58.   String25   = string [25];
  59.   String80   = string [80];
  60.  
  61.   LocOb = Object
  62.     Row, Col : byte;
  63.     Procedure AcceptLoc (R, C : byte);
  64.     Procedure ReportLoc (Var R, C : byte);
  65.     Procedure GotoRC;
  66.   end;
  67.  
  68.   TimeOb = Object
  69.     Hour,
  70.     Minute,
  71.     Second,
  72.     Sec100 : word;
  73.  
  74.     Function PcTime : String12;                  { '10:36:09 pm' }
  75.     Function ShortTime : String6;                { '9:07p' }
  76.   end;
  77.  
  78.   DateOb = Object (TimeOb)
  79.     Year,
  80.     Month,
  81.     Day,
  82.     DayOfWeek : word;
  83.  
  84.     Function  LeapYear      : boolean;           { returns true if leap year }
  85.     Function  ValidDate     : boolean;           { returns true if valid date }
  86.     Function  GetDayOfWeek  : word;              { returns day of week }
  87.     Function  DayOfTheWeek3 : String3;           { returns 'Tue' }
  88.     Function  DayOfTheWeek  : String12;          { returns 'Tuesday' }
  89.  
  90.     Procedure GetToday;                          { put today's date in }
  91.                                                  { DateOb variables }
  92.     Procedure AcceptDate (Y, M, D : word);       { accept user variables }
  93.     Procedure AdvanceDate;                       { advances date one day }
  94.  
  95.     Function  PcDate        : String12;          { ' 3-05-88' }
  96.     Function  LogDate       : String12;          { ' 5-Mar-88' }
  97.     Function  StarDate      : String12;          { '8803.05' }
  98.     Function  FormalDate    : String25;          { 'March 5, 1988' }
  99.     Function  AbbrevDate    : String25;          { 'Tue, 3-05-88' }
  100.     Function  FullDate      : String25;          { 'Tuesday, March 5, 1988' }
  101.     Function  TimeStamp     : String25;          { 'Tue, 12-23-86, 11:01p' }
  102.   end;
  103.  
  104. CONST
  105.     Yes = True;
  106.     No  = False;
  107.     On  = True;
  108.     Off = False;
  109.  
  110.   SoundFlag   : Boolean = True;
  111.   MusicFlag   : Boolean = True;
  112.   ClickFlag   : Boolean = True;
  113.   ClockFlag   : Boolean = False;
  114.  
  115.   SingleLine  = #218#192#191#217#196#179;
  116.   DoubleLine  = #201#200#187#188#205#186;
  117.  
  118.   Blinking    : byte = 128;
  119.  
  120.   BlackBlack            = $00;
  121.   BlueBlack             = $01;
  122.   GreenBlack            = $02;
  123.   CyanBlack             = $03;
  124.   RedBlack              = $04;
  125.   MagentaBlack          = $05;
  126.   BrownBlack            = $06;
  127.   LightGrayBlack        = $07;
  128.   DarkGrayBlack         = $08;
  129.   LightBlueBlack        = $09;
  130.   LightGreenBlack       = $0A;
  131.   LightCyanBlack        = $0B;
  132.   LightRedBlack         = $0C;
  133.   LightMagentaBlack     = $0D;
  134.   YellowBlack           = $0E;
  135.   WhiteBlack            = $0F;
  136.   BlackBlue             = $10;
  137.   BlueBlue              = $11;
  138.   GreenBlue             = $12;
  139.   CyanBlue              = $13;
  140.   RedBlue               = $14;
  141.   MagentaBlue           = $15;
  142.   BrownBlue             = $16;
  143.   LightGrayBlue         = $17;
  144.   DarkGrayBlue          = $18;
  145.   LightBlueBlue         = $19;
  146.   LightGreenBlue        = $1A;
  147.   LightCyanBlue         = $1B;
  148.   LightRedBlue          = $1C;
  149.   LightMagentaBlue      = $1D;
  150.   YellowBlue            = $1E;
  151.   WhiteBlue             = $1F;
  152.   BlackGreen            = $20;
  153.   BlueGreen             = $21;
  154.   GreenGreen            = $22;
  155.   CyanGreen             = $23;
  156.   RedGreen              = $24;
  157.   MagentaGreen          = $25;
  158.   BrownGreen            = $26;
  159.   LightGrayGreen        = $27;
  160.   DarkGrayGreen         = $28;
  161.   LightBlueGreen        = $29;
  162.   LightGreenGreen       = $2A;
  163.   LightCyanGreen        = $2B;
  164.   LightRedGreen         = $2C;
  165.   LightMagentaGreen     = $2D;
  166.   YellowGreen           = $2E;
  167.   WhiteGreen            = $2F;
  168.   BlackCyan             = $30;
  169.   BlueCyan              = $31;
  170.   GreenCyan             = $32;
  171.   CyanCyan              = $33;
  172.   RedCyan               = $34;
  173.   MagentaCyan           = $35;
  174.   BrownCyan             = $36;
  175.   LightGrayCyan         = $37;
  176.   DarkGrayCyan          = $38;
  177.   LightBlueCyan         = $39;
  178.   LightGreenCyan        = $3A;
  179.   LightCyanCyan         = $3B;
  180.   LightRedCyan          = $3C;
  181.   LightMagentaCyan      = $3D;
  182.   YellowCyan            = $3E;
  183.   WhiteCyan             = $3F;
  184.   BlackRed              = $40;
  185.   BlueRed               = $41;
  186.   GreenRed              = $42;
  187.   CyanRed               = $43;
  188.   RedRed                = $44;
  189.   MagentaRed            = $45;
  190.   BrownRed              = $46;
  191.   LightGrayRed          = $47;
  192.   DarkGrayRed           = $48;
  193.   LightBlueRed          = $49;
  194.   LightGreenRed         = $4A;
  195.   LightCyanRed          = $4B;
  196.   LightRedRed           = $4C;
  197.   LightMagentaRed       = $4D;
  198.   YellowRed             = $4E;
  199.   WhiteRed              = $4F;
  200.   BlackMagenta          = $50;
  201.   BlueMagenta           = $51;
  202.   GreenMagenta          = $52;
  203.   CyanMagenta           = $53;
  204.   RedMagenta            = $54;
  205.   MagentaMagenta        = $55;
  206.   BrownMagenta          = $56;
  207.   LightGrayMagenta      = $57;
  208.   DarkGrayMagenta       = $58;
  209.   LightBlueMagenta      = $59;
  210.   LightGreenMagenta     = $5A;
  211.   LightCyanMagenta      = $5B;
  212.   LightRedMagenta       = $5C;
  213.   LightMagentaMagenta   = $5D;
  214.   YellowMagenta         = $5E;
  215.   WhiteMagenta          = $5F;
  216.   BlackBrown            = $60;
  217.   BlueBrown             = $61;
  218.   GreenBrown            = $62;
  219.   CyanBrown             = $63;
  220.   RedBrown              = $64;
  221.   MagentaBrown          = $65;
  222.   BrownBrown            = $66;
  223.   LightGrayBrown        = $67;
  224.   DarkGrayBrown         = $68;
  225.   LightBlueBrown        = $69;
  226.   LightGreenBrown       = $6A;
  227.   LightCyanBrown        = $6B;
  228.   LightRedBrown         = $6C;
  229.   LightMagentaBrown     = $6D;
  230.   YellowBrown           = $6E;
  231.   WhiteBrown            = $6F;
  232.   BlackLightGray        = $70;
  233.   BlueLightGray         = $71;
  234.   GreenLightGray        = $72;
  235.   CyanLightGray         = $73;
  236.   RedLightGray          = $74;
  237.   MagentaLightGray      = $75;
  238.   BrownLightGray        = $76;
  239.   LightGrayLightGray    = $77;
  240.   DarkGrayLightGray     = $78;
  241.   LightBlueLightGray    = $79;
  242.   LightGreenLightGray   = $7A;
  243.   LightCyanLightGray    = $7B;
  244.   LightRedLightGray     = $7C;
  245.   LightMagentaLightGray = $7D;
  246.   YellowLightGray       = $7E;
  247.   WhiteLightGray        = $7F;
  248.  
  249.   DayName     : Array [0 .. 6] of String [9] =
  250.                         ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
  251.                          'Thursday', 'Friday', 'Saturday');
  252.   MonthName   : Array [1 .. 12] of String [9] =
  253.                         ('January', 'February', 'March', 'April',
  254.                          'May', 'June', 'July', 'August', 'September',
  255.                          'October', 'November', 'December');
  256.   MonthLength : Array [1 .. 12] of Byte =
  257.                        (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  258.  
  259.   TimeUntilBlank : LongInt = 180000;             { approx 3 minutes }
  260.  
  261.   BackSpace       = #8;
  262.   Tab             = #9;
  263.   Enter           = #13;
  264.   Esc             = #27;
  265.   CtrlBackSpace   = #127;
  266.   ShiftTab        = #143;
  267.  
  268.   ShiftHomeKey    = #177;
  269.   ShiftUpArrow    = #178;
  270.   ShiftPageUp     = #179;
  271.   ShiftLeftArrow  = #180;
  272.   ShiftRightArrow = #181;
  273.   ShiftEndKey     = #182;
  274.   ShiftDownArrow  = #183;
  275.   ShiftPageDown   = #184;
  276.   ShiftInsertKey  = #185;
  277.   ShiftDeleteKey  = #186;
  278.  
  279.   F1         = #187;
  280.   F2         = #188;
  281.   F3         = #189;
  282.   F4         = #190;
  283.   F5         = #191;
  284.   F6         = #192;
  285.   F7         = #193;
  286.   F8         = #194;
  287.   F9         = #195;
  288.   F10        = #196;
  289.  
  290.   HomeKey    = #199;
  291.   UpArrow    = #200;
  292.   PageUp     = #201;
  293.   LeftArrow  = #203;
  294.   RightArrow = #205;
  295.   EndKey     = #207;
  296.   DownArrow  = #208;
  297.   PageDown   = #209;
  298.   InsertKey  = #210;
  299.   DeleteKey  = #211;
  300.  
  301.   ShiftF1    = #212;
  302.   ShiftF2    = #213;
  303.   ShiftF3    = #214;
  304.   ShiftF4    = #215;
  305.   ShiftF5    = #216;
  306.   ShiftF6    = #217;
  307.   ShiftF7    = #218;
  308.   ShiftF8    = #219;
  309.   ShiftF9    = #220;
  310.   ShiftF10   = #221;
  311.  
  312.   CtrlF1     = #222;
  313.   CtrlF2     = #223;
  314.   CtrlF3     = #224;
  315.   CtrlF4     = #225;
  316.   CtrlF5     = #226;
  317.   CtrlF6     = #227;
  318.   CtrlF7     = #228;
  319.   CtrlF8     = #229;
  320.   CtrlF9     = #230;
  321.   CtrlF10    = #231;
  322.  
  323.   AltF1      = #232;
  324.   AltF2      = #233;
  325.   AltF3      = #234;
  326.   AltF4      = #235;
  327.   AltF5      = #236;
  328.   AltF6      = #237;
  329.   AltF7      = #238;
  330.   AltF8      = #239;
  331.   AltF9      = #240;
  332.   AltF10     = #241;
  333.  
  334.   CtrlLeftArrow   = #243;
  335.   CtrlRightArrow  = #244;
  336.   CtrlEndKey      = #245;
  337.   CtrlPageDown    = #246;
  338.   CtrlHomeKey     = #247;
  339.   CtrlPageUp      = #248;        { Scancode-shift sees CtrlPageUp as ^D }
  340.                                  { ReadChar translates it to #248 }
  341.  
  342.   CtrlShiftLeftArrow   = #249;
  343.   CtrlShiftRightArrow  = #250;
  344.   CtrlShiftEndKey      = #251;
  345.   CtrlShiftPageDown    = #252;
  346.   CtrlShiftHomeKey     = #253;
  347.   CtrlShiftPageUp      = #254;
  348.  
  349. VAR
  350.   RightShiftKey,
  351.   LeftShiftKey,
  352.   ShiftKey,
  353.   ControlKey,
  354.   AltKey,
  355.   ScrlLock,
  356.   NumLock,
  357.   CapsLock,
  358.   InsLock       : boolean;
  359.  
  360.   LogOnTime     : LongInt;                       { time program started }
  361.  
  362. { ========================================================================= }
  363.  
  364. FUNCTION Max (Num1, Num2 : integer) : integer;
  365.  
  366. FUNCTION Min (Num1, Num2 : integer) : integer;
  367.  
  368. PROCEDURE SetBitTo1 (VAR B : byte;  Bit: byte);
  369.  
  370. PROCEDURE SetBitTo0 (VAR B : byte;  Bit: byte);
  371.  
  372. PROCEDURE Click;
  373.  
  374. PROCEDURE Beep;
  375.  
  376. PROCEDURE Wait;
  377. { waits for any keyboard activity }
  378.  
  379. PROCEDURE PauseWithPrompt (Prompt : string);
  380. { 'Press any key to continue. . . . ' }
  381.  
  382. PROCEDURE Pause;
  383. { Prompts:  'Press any key to continue. . . . ' }
  384.  
  385. PROCEDURE BlankLine (Row, Len, Attr : byte);
  386. { writes a blank line to screen }
  387.  
  388. FUNCTION  ExistAnyFile (FileName : String) : boolean;
  389. { does this file exist? }
  390.  
  391. PROCEDURE AddFileExt (FileName, Ext : string);
  392. { if no file extension, adds specified extension }
  393.  
  394. PROCEDURE ShowTime;
  395. { Puts a time string in the upper right corner of the screen }
  396.  
  397. PROCEDURE ShowToday;
  398. { Puts date and time in the upper right corner of the screen }
  399.  
  400. PROCEDURE ResetDate;
  401. { use for advancing date and resetting it after midnight }
  402.  
  403. FUNCTION  WaitingPatiently (TimeToWait : LongInt) : boolean;
  404. { If no key is pressed before time is up, function returns true. }
  405.  
  406. PROCEDURE DisposeNilWindow (VAR W : WindowPtr);
  407. { Disposes of window, returns WindowPtr to nil. }
  408.  
  409. PROCEDURE OpenProgram;
  410. { Saves existing Dos screen. }
  411.  
  412. PROCEDURE CloseProgram;
  413. { Returns to original Dos screen. }
  414.  
  415. { ========================================================================= }
  416. IMPLEMENTATION
  417. { ========================================================================= }
  418.  
  419. VAR
  420.   SaveCursorLoc : LocOb;                         { location of cursor }
  421.  
  422.   SaveDosCursor : word;                          { cursor at start }
  423.   SaveCBreak    : boolean;                       { Ctrl-C break at start }
  424.   SaveDosScreen : PackedWindowPtr;               { screen at start }
  425.  
  426.   ExitSave      : pointer;                       { for ExitProc }
  427.  
  428. { ========================================================================= }
  429.  
  430. FUNCTION Max (Num1, Num2 : integer) : integer;
  431. Begin
  432. If Num1 > Num2 Then Max := Num1 Else Max := Num2;
  433. End;
  434.  
  435. { ========================================================================= }
  436.  
  437. FUNCTION Min (Num1, Num2 : integer) : integer;
  438. Begin
  439. If Num1 < Num2 Then Min := Num1 Else Min := Num2;
  440. End;
  441.  
  442. { ========================================================================= }
  443.  
  444. PROCEDURE SetBitTo1 (VAR B : byte;  Bit: byte);
  445. BEGIN
  446. B := B or (1 shl Bit)
  447. END;
  448.  
  449. { ========================================================================= }
  450.  
  451. PROCEDURE SetBitTo0 (VAR B : byte;  Bit: byte);
  452. BEGIN
  453. B := B and not (1 shl Bit)
  454. END;
  455.  
  456. { ========================================================================= }
  457.  
  458. PROCEDURE Click;
  459. BEGIN
  460.   If ClickFlag then begin
  461.     Sound (220);
  462.     Delay (4);
  463.     NoSound;
  464.     end;
  465. END;
  466.  
  467. { ========================================================================= }
  468.  
  469. PROCEDURE Beep;
  470.   Begin
  471.   If SoundFlag Then
  472.     Begin
  473.     Sound (440);
  474.     Delay (15);
  475.     NoSound;
  476.     End;
  477.   End;
  478.  
  479. { ========================================================================= }
  480.  
  481. PROCEDURE Wait;                                  { 8906.01 }
  482. { Waits for any keyboard activity.  }
  483. { Recognizes normal, control, & lock keys.  Flushes key if pressed.  }
  484.  
  485. VAR
  486.   Ch             : char;
  487.   SaveByte       : byte;
  488.   KeyStates      : byte;
  489.   KeyStateByte   : byte absolute $40:$17;
  490.  
  491. BEGIN
  492.   SaveByte := KeyStateByte;                      { save lock keys }
  493.   KeyStates := KeyStateByte;
  494.   Repeat Until Keypressed or (KeyStates <> KeyStateByte);
  495.   If KeyPressed then
  496.     while Keypressed do Ch := ReadKey;           { flush buffer }
  497.  
  498. { leave changed new states of alt, ctrl, shift keys }
  499.   KeyStateByte := (KeyStateByte and $F) or (SaveByte and $F0);
  500. END;
  501.  
  502. { ========================================================================= }
  503.  
  504. PROCEDURE PauseWithPrompt (Prompt : string);
  505. {
  506.   Prints centered prompt, then waits for key to be pressed.
  507. }
  508.  
  509. BEGIN
  510. WriteLn;
  511. FastWriteWindow (Prompt, WhereY, 40 - Trunc (Length (Prompt)/2), LightRed);
  512. Wait;
  513. END;
  514.  
  515. { ========================================================================= }
  516.  
  517. PROCEDURE Pause;
  518.  
  519. BEGIN
  520. PauseWithPrompt ('Press any key to continue.');
  521. END;
  522.  
  523. { ========================================================================= }
  524.  
  525. PROCEDURE BlankLine (Row, Len, Attr : Byte);
  526.  
  527. BEGIN
  528.   FastWriteWindow (CharStr (' ', Len), Row, 1, Attr);
  529. END;
  530.  
  531. { ========================================================================= }
  532.  
  533. FUNCTION ExistAnyFile (FileName : String) : Boolean;
  534.  
  535. VAR
  536.   SaveMode : Byte;
  537.  
  538. Begin
  539.    SaveMode := FileMode;
  540.    FileMode := 0;
  541.    ExistAnyFile := ExistFile (FileName);
  542.    FileMode := SaveMode;
  543. End;
  544.  
  545. { ========================================================================= }
  546.  
  547. PROCEDURE AddFileExt (FileName, Ext : string);
  548.  
  549. Begin
  550.   If Pos ('.', FileName) = 0 Then FileName := FileName + '.' + Ext;
  551. End;
  552.  
  553. { ========================================================================= }
  554.  
  555. PROCEDURE LocOb.AcceptLoc (R, C : byte);
  556.  
  557. BEGIN
  558.   Row := R;
  559.   Col := C;
  560. END;
  561.  
  562. { ========================================================================= }
  563.  
  564. PROCEDURE LocOb.ReportLoc (Var R, C : byte);
  565.  
  566. BEGIN
  567.   R := Row;
  568.   C := Col;
  569. END;
  570.  
  571. { ========================================================================= }
  572.  
  573. PROCEDURE LocOb.GotoRC;
  574.  
  575. BEGIN
  576.   Gotoxy (Col, Row);
  577. END;
  578.  
  579. { ========================================================================= }
  580.  
  581. FUNCTION ZeroFix (NumStr : String2) : String2;
  582.  
  583. BEGIN
  584.   If NumStr [0] = #1 Then Insert ('0', NumStr, 1);
  585.   ZeroFix := NumStr;
  586. END;
  587.  
  588. { ========================================================================= }
  589.  
  590. FUNCTION SpaceFix (NumStr : String2) : String2;
  591.  
  592. BEGIN
  593.   If NumStr [0] = #1 Then Insert (' ', NumStr, 1);
  594.   SpaceFix := NumStr;
  595. END;
  596.  
  597. { ========================================================================= }
  598.  
  599. FUNCTION TimeOb.PcTime : String12;
  600. { Returns a string showing the current time in this format: `10:36:09 pm'.  }
  601.  
  602. VAR
  603.   AmPm : string [2];
  604.  
  605. BEGIN
  606.   GetTime (Hour, Minute, Second, Sec100);
  607.  
  608.   Case Hour Of
  609.     0           : Begin
  610.                   AmPm := 'am';
  611.                   Hour := 12;
  612.                   End;
  613.     1 .. 11     : AmPm := 'am';
  614.     12          : AmPm := 'pm';
  615.     13 .. 23    : Begin
  616.                   AmPm := 'pm';
  617.                   Hour := Hour - 12;
  618.                   End;
  619.     End;  { Case Hour Of }
  620.  
  621.     PCtime := SpaceFix (Long2Str (Hour)) + ':' +
  622.               ZeroFix (Long2Str (Minute)) + ':' +
  623.               ZeroFix (Long2Str (Second)) + ' ' + AmPm;
  624. End;
  625.  
  626. { ========================================================================= }
  627.  
  628. FUNCTION TimeOb.ShortTime : String6;
  629. { Returns time in format:  '9:07p' }
  630.  
  631. VAR
  632.   TempStr : String12;
  633.   Len     : byte absolute TempStr;
  634.  
  635. BEGIN
  636.   TempStr := PcTime;
  637.   Delete (TempStr, Len, 1);
  638.   Delete (TempStr, Len - 4, 4);
  639.   ShortTime := TempStr;
  640. END;
  641.  
  642. { ========================================================================= }
  643.  
  644. FUNCTION DateOb.LeapYear : boolean;
  645. { Returns true if year is leap year }
  646.  
  647. BEGIN
  648.   LeapYear := ((Year mod 4 = 0)
  649.                   and
  650.               (Year mod 100 <> 0))
  651.                    or
  652.               (Year mod 400 = 0);
  653. END;
  654.  
  655. { ========================================================================= }
  656.  
  657. FUNCTION DateOb.ValidDate: boolean;
  658. { Returns true if year is leap year }
  659.  
  660. BEGIN
  661.   ValidDate := (Month mod 12 <= 11)
  662.                  and
  663.                (Day <= (MonthLength [Month] + ord (LeapYear)));
  664. END;
  665.  
  666. { ========================================================================= }
  667.  
  668. FUNCTION DateOb.GetDayOfWeek : Word;
  669. { Gets the day of the week as a number. }
  670.  
  671. VAR
  672.   Y,
  673.   Loop : Word;
  674.  
  675. BEGIN
  676.   MonthLength [2] := 28 + Ord (LeapYear);        { How long is Feb? }
  677.  
  678. { Calculate what day is today, allowing for all previous leap years.      }
  679.   Y := Year MOD 7 + Pred (Day) - ord (LeapYear) +
  680.        Year DIV 4 - Year DIV 100 + Year DIV 400;
  681.   For Loop := 1 to Pred (Month) do
  682.     Y := Y + MonthLength [Loop];
  683.   GetDayOfWeek := Y mod 7;
  684. END;
  685.  
  686. { ========================================================================= }
  687.  
  688. FUNCTION DateOb.DayOfTheWeek3 : String3;
  689. { Returns:  `Tue' }
  690.  
  691. BEGIN
  692.   DayOfTheWeek3 := Copy (DayName [DayOfWeek], 1, 3);
  693. END;
  694.  
  695. { ========================================================================= }
  696.  
  697. FUNCTION DateOb.DayOfTheWeek : String12;
  698. { Returns:  `Tuesday' }
  699.  
  700. BEGIN
  701.   DayOfTheWeek := DayName [DayOfWeek];
  702. END;
  703.  
  704. { ========================================================================= }
  705.  
  706. PROCEDURE DateOb.GetToday;
  707.  
  708. BEGIN
  709.   GetDate (Year, Month, Day, DayOfWeek);
  710. END;
  711.  
  712. { ========================================================================= }
  713.  
  714. PROCEDURE DateOb.AcceptDate (Y, M, D : word);
  715.  
  716. BEGIN
  717.   Year := Y;
  718.   Month := M;
  719.   Day := D;
  720.   DayOfWeek := GetDayOfWeek;
  721. END;
  722.  
  723. { ========================================================================= }
  724.  
  725. PROCEDURE DateOb.AdvanceDate;
  726. { Advances date by one. }
  727.  
  728. VAR
  729.   Loop      : Word;
  730.  
  731. BEGIN
  732.   MonthLength [2] := 28 + Ord (LeapYear);        { How long is Feb? }
  733.   inc (DayOfWeek);
  734.   DayOfWeek := DayOfWeek mod 7;
  735.   inc (Day);
  736.   If Day > MonthLength [Month] then begin
  737.     Day := 1;
  738.     inc (Month);
  739.     If Month > 12 then begin
  740.       Month := 1;
  741.       inc (Year);
  742.       end;
  743.     end;
  744. END;
  745.  
  746. { ========================================================================= }
  747.  
  748. FUNCTION DateOb.PcDate : String12;
  749. { Returns Date in PC format:  ' 3-05-88' }
  750.  
  751. BEGIN
  752.   If not ValidDate then GetToday;
  753.   PCdate := SpaceFix (Long2Str (Month)) + '-' +
  754.             ZeroFix (Long2Str (Day)) + '-' +
  755.             ZeroFix (Long2Str (Year mod 100));
  756. END;
  757.  
  758. { ========================================================================= }
  759.  
  760. FUNCTION DateOb.LogDate : String12;
  761. { Returns Date in Log format:  ' 5-Mar-88' }
  762.  
  763. BEGIN
  764.   If not ValidDate then GetToday;
  765.   LogDate := SpaceFix (Long2Str (Day)) + '-' +
  766.              Copy (MonthName [Month], 1, 3) + '-' +
  767.              ZeroFix (Long2Str (Year mod 100));
  768. END;
  769.  
  770. { ========================================================================= }
  771.  
  772. FUNCTION DateOb.StarDate : String12;
  773. { Returns Date in StarDate format:  '8803.05' }
  774.  
  775. BEGIN
  776.   If not ValidDate then GetToday;
  777.   StarDate := ZeroFix (Long2Str (Year mod 100)) +
  778.               ZeroFix (Long2Str (Month)) + '.' +
  779.               ZeroFix (Long2Str (Day));
  780. END;
  781.  
  782. { ========================================================================= }
  783.  
  784. FUNCTION DateOb.FormalDate : String25;
  785. { Returns Date:  'March 5, 1988' }
  786.  
  787. BEGIN
  788.   If not ValidDate then GetToday;
  789.   FormalDate := MonthName [Month] + ' ' +
  790.                 Long2Str (Day) + ', ' +
  791.                 Long2Str (Year);
  792. END;
  793.  
  794. { ========================================================================= }
  795.  
  796. FUNCTION DateOb.AbbrevDate: String25;
  797. { Returns Date:  'March 5, 1988' }
  798.  
  799. BEGIN
  800.   If not ValidDate then GetToday;
  801.   AbbrevDate := DayOfTheWeek3 + ', ' + Trim (PcDate);
  802. END;
  803.  
  804. { ========================================================================= }
  805.  
  806. FUNCTION DateOb.FullDate: String25;
  807. { Returns Date:  'March 5, 1988' }
  808.  
  809. BEGIN
  810.   If not ValidDate then GetToday;
  811.   FullDate := DayOfTheWeek + ', ' +
  812.               MonthName [Month] + ' ' +
  813.               Long2Str (Day) + ', ' +
  814.               Long2Str (Year);
  815. END;
  816.  
  817. { ========================================================================= }
  818.  
  819. FUNCTION DateOb.TimeStamp : String25;
  820. { Returns:  `Tue, 12-23-86, 11:01p' }
  821.  
  822. BEGIN
  823.   TimeStamp := AbbrevDate + ', ' + ShortTime;
  824. END;
  825.  
  826. { ========================================================================= }
  827.  
  828. PROCEDURE ShowTime;
  829. { Puts a time string in the upper right corner of the screen }
  830.  
  831. VAR
  832.   TimeStamp : TimeOb;
  833.  
  834. BEGIN
  835.   FastWrite (TimeStamp.PcTime, 1, 70, 10);
  836. END;
  837.  
  838. { ========================================================================= }
  839.  
  840. PROCEDURE ShowToday;
  841. { Puts time and date in the upper right corner of the screen }
  842.  
  843. VAR
  844.   DateStamp : DateOb;
  845.  
  846. BEGIN
  847.   FastWrite (DateStamp.AbbrevDate, 1, 68, 10);
  848.   FastWrite (DateStamp.PcTime, 2, 68, 10);
  849. END;
  850.  
  851. { ========================================================================= }
  852.  
  853. PROCEDURE ResetDate;
  854.  
  855. VAR
  856.   TimeStamp : DateOb;
  857.  
  858. BEGIN
  859. With TimeStamp do begin
  860.   GetToday;
  861.   AdvanceDate;
  862.   SetDate (Year, Month, Day);
  863.   LogOnTime := TimeMs;                           { get new LogOnTime }
  864.   end;
  865. END;
  866.  
  867. { ========================================================================= }
  868.  
  869. FUNCTION WaitingPatiently (TimeToWait : LongInt) : boolean;
  870. { Returns false if key is pressed before time is up. }
  871. { Will display date and time in upper right corner if ClockFlag is true. }
  872.  
  873. VAR
  874.   Start, Stop  : LongInt;
  875.   KeyStates    : byte;
  876.   KeyStateByte : byte absolute $40:$17;
  877.  
  878. BEGIN
  879.   WaitingPatiently := false;
  880.   If TimeMs < LogOnTime Then ResetDate;
  881.   Start := TimeMs;
  882.   KeyStates := KeyStateByte;
  883.   Repeat
  884.     If ClockFlag then ShowToday;
  885.     Stop := TimeMs;
  886.     If Stop < Start then begin
  887.       ResetDate;
  888.       Start := TimeMs;
  889.       End;
  890.     If KeyStates <> KeyStateByte then begin
  891.       KeyStates := KeyStateByte;
  892.       Start := TimeMs;
  893.       end;
  894.     If KeyPressed then exit;
  895.   Until
  896.     (Stop - Start) > TimeToWait;
  897.   WaitingPatiently := true;
  898. END;
  899.  
  900. { ========================================================================= }
  901.  
  902. PROCEDURE DisposeNilWindow (VAR W : WindowPtr);
  903. {
  904.   Erases window, disposes it, resets WindowPtr to nil.
  905. }
  906. BEGIN
  907. If W <> Nil then
  908.   If SetTopWindow (W) then begin
  909.         W := EraseTopWindow;
  910.       DisposeWindow (W);
  911.       W := Nil;
  912.         end;
  913. END;
  914.  
  915. { ========================================================================= }
  916.  
  917. PROCEDURE OpenProgram;
  918.  
  919. BEGIN
  920.   SaveDosScreen := PackWindow (1, 1, 80, 25);
  921.   HiddenCursor;
  922.   ClrScr;
  923. END;
  924.  
  925. { ========================================================================= }
  926.  
  927. PROCEDURE CloseProgram;
  928.  
  929. BEGIN
  930.   DispPackedWindow (SaveDosScreen);              { restore underlying screen }
  931.   DisposePackedWindow (SaveDosScreen);           { dispose where it's saved }
  932.   SaveCursorLoc.GotoRC;                          { restore cursor loc }
  933. END;
  934.  
  935. { ========================================================================= }
  936.  
  937. {$F+} PROCEDURE ExitProgram; {$F-}
  938.  
  939.  
  940. BEGIN
  941.   NormVideo;                                     { restore original attr }
  942.   SetCursorSize (hi (SaveDosCursor),
  943.                  lo (SaveDosCursor));            { restore cursor }
  944.  
  945.   SetCBreak (SaveCBreak);                        { restore Ctrl-C }
  946.   ExitProc := ExitSave;                          { Say Goodnight Gracie }
  947. END;
  948.  
  949. { ========================================================================= }
  950. {  Initialization :                                                         }
  951. { ========================================================================= }
  952.  
  953. BEGIN
  954.   LogOnTime    := TimeMs;                        { what time did we start? }
  955.  
  956.   GetCBreak (SaveCBreak);                        { get Ctrl-C status }
  957.   SetCBreak (false);                             { turn Ctrl-C off }
  958.   CheckBreak := false;                           { turn off Ctrl-Break }
  959.  
  960.   SaveCursorLoc.AcceptLoc
  961.     (pred (WhereY), WhereX);                     { save cursor location }
  962.   SaveDosCursor := CursorTypeSL;                 { Dos cursor is what? }
  963.   MapColors     := (CurrentDisplay = MonoHerc);  { B/W display? }
  964.   TextAttr      := MapColor (YellowBlack);       { set attr }
  965.  
  966.   ExitSave := ExitProc;                          { set up exit proc }
  967.   ExitProc := @ExitProgram;                      { get pointer }
  968. END.
  969.  
  970. { ========================================================================= }
  971. { ========================================================================= }
  972.  
  973.